package com.jiegui.payinterface.handler.impl.wxpay;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.jiegui.common.utils.AmountUtils;
import com.jiegui.payinterface.bean.PaymentRes;
import com.jiegui.payinterface.enums.PaymentStatus;
import com.jiegui.payinterface.handler.PaymentHandler;
import com.jiegui.payinterface.handler.impl.wxpay.utils.XmlUtils;
import com.jiegui.payinterface.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Properties;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @description:
 * @author: wuqicheng
 * @time: 14/4/2023 上午 11:16
 */
@Slf4j
@Service("wxPayThaHandler")
public class WxPayThaHandlerImpl  implements PaymentHandler {

    @Override
    public PaymentRes pay(Map<String, String> map) {

        SortedMap<String, String> treeMap = new TreeMap<>();
        PaymentRes res = new PaymentRes();
        res.setBillCode(map.get("billCode"));
        Properties properties = JSON.parseObject(map.get("tradeConfigs"), new TypeReference<Properties>() {});
        SortedMap<String, String> resMap =new TreeMap<>();
        resMap.put("sub_mch_id", properties.getProperty("sub_mch_id"));
        resMap.put("sub_appid",properties.getProperty("sub_appid"));
        resMap.put("sign_type", "MD5");
        resMap.put("body", "充值");
        resMap.put("fee_type", properties.getProperty("fee_type"));
        resMap.put("version", "1.0");
        resMap.put("spbill_create_ip", "127.0.0.1");
        resMap.put("body", map.get("remark"));
        resMap.put("out_trade_no", map.get("billCode"));
        resMap.put("total_fee", AmountUtils.amountToFen(Double.parseDouble(map.get("amount"))));
        resMap.put("notify_url", map.get("notifyUrl") + "?interfaceCode=" + map.get("interfaceCode"));
        resMap.put("attach", map.get("attach"));
        resMap.put("trade_type", map.get("payType"));
        resMap.put("appid", properties.getProperty("appid"));
        resMap.put("sub_openid", map.get("userId"));
        resMap.put("mch_id", properties.getProperty("mchId"));
        resMap.put("nonce_str", RandomStringUtils.randomAlphanumeric(8));
        log.info("微信支付请求报文: {}", resMap);
        // 请求参数签名
        resMap.put("sign", XmlUtils.createSign(resMap, properties.getProperty("mchKey")));


        try {
            String xmlStr = XmlUtils.parseXML(resMap);
            log.info("微信支付请求报文(XML): {}", xmlStr);
            String resultStr = HttpUtil.request(properties.getProperty("payUrl"), xmlStr, "POST");
            log.info("微信支付响应消息(XML):: {}", resultStr);

            SortedMap<String, String> result = XmlUtils.getMapFromXml(resultStr);
            log.info("微信支付响应消息: {}", result);
            if ("SUCCESS".equals(result.get("result_code")) && "SUCCESS".equals(result.get("result_code"))) {
                // 验证签名
                String sign = XmlUtils.createSign(result, properties.getProperty("mchKey"));
                if (!sign.equals(result.get("sign"))) {
                    res.setStatus(PaymentStatus.FAILURE);
                    res.setResponseCode("999");
                    res.setResponseMessage("签名验证失败");
                    return res;
                }

                if ("JSAPI".equals(map.get("payType"))) {
                    res.remove("billCode");
                    res.put("package", "prepay_id="+ result.get("prepay_id"));
                    res.put("nonceStr", result.get("nonce_str"));
                    res.put("signType", "MD5");
                    res.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
                    res.put("appId", result.get("sub_appid"));
                    res.put("paySign", XmlUtils.createSign(res.toSortMap(), properties.getProperty("mchKey")));
                    res.setBillCode(map.get("billCode"));
                }

                if (StringUtils.equals(map.get("payType"), "NATIVE")) {
                    res.put("code_url", result.get("code_url"));
                }

                res.setStatus(PaymentStatus.SUCCESS);
                res.setResponseCode(result.get("result_code"));
                res.setResponseMessage("交易成功");
            } else {
                res.setStatus(PaymentStatus.FAILURE);
                res.setResponseCode(result.get("err_code"));
                res.setResponseMessage(result.get("err_code_des"));
                log.error("微信支付请求失败: 错误代码={}  请求描述={}  错误描述={}", result.get("err_code"), result.get("return_msg"), result.get("err_code_des"));
            }

        } catch (Exception e) {
            log.error("微信支付请求异常:", e);
            res.setStatus(PaymentStatus.FAILURE);
            res.setResponseMessage("微信支付请求异常");
        }

        return res;
    }

    @Override
    public PaymentRes query(Map<String, String> map) {
        return null;
    }

    @Override
    public PaymentRes refund(Map<String, String> map) {
        return null;
    }

    @Override
    public PaymentRes drawcash(Map<String, String> map) {
        return null;
    }

    @Override
    public PaymentRes queryDrawCash(Map<String, String> map) throws Exception {
        return null;
    }
}
